package com.cn.serverline.lineicp.productionLine.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException;
import com.cn.serverline.lineicp.productionLine.constants.ProcessStepsConstant;
import com.cn.serverline.lineicp.productionLine.entity.ProcessSteps;
import com.cn.serverline.lineicp.productionLine.entity.ProductionProcesses;
import com.cn.serverline.lineicp.productionLine.enums.ProcessStepsException;
import com.cn.serverline.lineicp.productionLine.enums.ProductionProcessesException;
import com.cn.serverline.lineicp.productionLine.mapper.ProcessStepsMapper;
import com.cn.serverline.lineicp.productionLine.mapper.ProductionProcessesMapper;
import com.cn.serverline.lineicp.productionLine.param.ProcessStepsAddParam;
import com.cn.serverline.lineicp.productionLine.param.ProcessStepsEditParam;
import com.cn.serverline.lineicp.productionLine.param.ProcessStepsIdParam;
import com.cn.serverline.lineicp.productionLine.param.ProcessStepsPageParam;
import com.cn.serverline.lineicp.productionLine.service.IProcessStepsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cn.serverline.lineicp.productionLine.util.DictUtil;
import org.springframework.stereotype.Service;
import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.roses.kernel.db.api.factory.PageResultFactory;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import cn.stylefeng.roses.kernel.db.api.factory.PageFactory;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;


/**
 * <p>
 * 工序工步表 服务实现类
 * </p>
 *
 * @author Gmr
 * @since 2024-07-30
 */
@Service("ProcessStepsServiceImpl")
public class ProcessStepsServiceImpl extends ServiceImpl<ProcessStepsMapper, ProcessSteps> implements IProcessStepsService {

    @Resource(name = "productionProcessesMapper")
    private ProductionProcessesMapper productionProcessesMapper;

    // 字典服务
    @Resource(name = "dictUtil")
    private DictUtil dictUtil;

    /**
     * 新增
     * @param addParam 请求参数
     */
    @Override
    public void add(ProcessStepsAddParam addParam) {

        // 校验工序是否存在
        getProductionProcesses(addParam.getProductionProcessesId());

        // 根据工序名称获取工序类型编码
        String code = dictUtil.getCodeByTypeAndName(ProcessStepsConstant.DICTIONARY_OF_PROCESS_TYPES, addParam.getStepName());
        if(StrUtil.isEmpty(code)) {
            throw new ServiceException(ProcessStepsException.PROCESS_TYPE_DOES_NOT_EXIST);
        }

        // 构建工步信息
        ProcessSteps processSteps = BeanUtil.copyProperties(addParam, ProcessSteps.class);
        processSteps.setStepName(code);
        this.save(processSteps);
    }

    /**
     * 删除
     * @param idParamList 请求参数
     */
    // TODO: 工步删除还有其他工步的关联表需要级联删除
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void del(List<ProcessStepsIdParam> idParamList) {

        // 获取所有工步id
        List<Long> idList = idParamList.stream()
                .map(ProcessStepsIdParam::getId)
                .collect(Collectors.toList());
        if(this.listByIds(idList).size() < idList.size()) {
            throw new ServiceException(ProcessStepsException.PROCESS_STEPS_DO_NOT_EXIST);
        }
        this.removeByIds(idList);
    }

    /**
     * 编辑
     * @param editParam 请求参数
     */
    @Override
    public void edit(ProcessStepsEditParam editParam) {
        ProcessSteps processSteps = getInfo(editParam.getId());
        // 根据工序名称获取工序类型编码
        String code = dictUtil.getCodeByTypeAndName(ProcessStepsConstant.DICTIONARY_OF_PROCESS_TYPES, editParam.getStepName());
        if(StrUtil.isEmpty(code)) {
            throw new ServiceException(ProcessStepsException.PROCESS_TYPE_DOES_NOT_EXIST);
        }
        BeanUtil.copyProperties(editParam, processSteps);
        processSteps.setStepName(code);
        this.updateById(processSteps);
    }

    /**
     * 查询详情
     * @param stepsIdParam 请求参数
     * @return 返回工序工步信息
     */
    @Override
    public ProcessSteps detail(ProcessStepsIdParam stepsIdParam) {
        return getInfo(stepsIdParam.getId());
    }

    /**
     * 分页查询
     * @param pageParam 请求参数
     * @return 返回分页结果
     */
    @Override
    public PageResult<ProcessSteps> findPage(ProcessStepsPageParam pageParam) {
        LambdaQueryWrapper<ProcessSteps> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProcessSteps::getProductionProcessesId, pageParam.getProductionProcessesId())
                .orderByAsc(ProcessSteps::getSort);

        Page<ProcessSteps> sysRolePage = this.page(PageFactory.defaultPage(), wrapper);
        return PageResultFactory.createPageResult(sysRolePage);
    }

    /**
     * 根据ID获取信息
     * @param id 工步ID
     * @return 工步信息
     */
    private ProcessSteps getInfo(Long id) {
        if(ObjectUtil.isEmpty(id)) {
            throw new ServiceException(ProcessStepsException.ID_NOT_EXIST);
        }

        ProcessSteps processSteps = this.getById(id);

        if(ObjectUtil.isEmpty(processSteps)) {
            throw new ServiceException(ProcessStepsException.PROCESS_STEPS_NOT_EXIST);
        }

        return processSteps;
    }

    /**
     * 根据工序ID获取工序
     * @param id 工序ID
     * @return 工序信息
     */
    private ProductionProcesses getProductionProcesses(Long id) {
        ProductionProcesses processes = productionProcessesMapper.selectById(id);
        if(ObjectUtil.isEmpty(processes)) {
            throw new ServiceException(ProductionProcessesException.PRODUCTION_PROCESSES_NOT_EXIST);
        }
        return processes;
    }
}
